package cgs_worksheet

import (
	"cgs-server/helper"
	"cgs-server/pkg/set"
	"cgs-server/server"
	"cgs-server/server/base"
	"cgs-server/server/model"
	"fmt"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo/options"
	"net/http"
	"net/url"
	"strconv"
	"strings"
)

func init() {
	server.Handle(http.MethodGet, "/api/Cgs/Worksheet/Export", Export, server.None)
	server.Get("/api/Cgs/Worksheet/GetWorksheetInfo", GetWorksheetInfo, "获取表单列表", server.Login)
	server.Get("/api/Cgs/Worksheet/GetWorksheetInfoById", GetWorksheetInfoById, "通过id获取表单", server.None)
	server.Post("/api/Cgs/Worksheet/Add", Add, "添加表单", server.Login)
	server.Post("/api/Cgs/Worksheet/UpdateName", UpdateName, "更新表单名称", server.Login)
	server.Post("/api/Cgs/Worksheet/Update", Update, "更新表单配置信息", server.Login)
	server.Post("/api/Cgs/Worksheet/UpdateFields", UpdateFields, "更新表单字段信息", server.Login)
	server.Post("/api/Cgs/Worksheet/Delete", DeleteLogic, "删除表单", server.Login)
	server.Post("/api/Cgs/Worksheet/AddRow", AddRow, "添加表单数据", server.Login)
	server.Post("/api/Cgs/Worksheet/AddRows", AddRows, "批量新建行记录", server.Login)
	server.Post("/api/Cgs/Worksheet/UpdateRow", UpdateRow, "更新一条表单数据", server.Login)
	server.Post("/api/Cgs/Worksheet/UpdateRowBatch", UpdateRowBatch, "批量更新表单数据", server.Login)
	server.Post("/api/Cgs/Worksheet/UpdateRowsByFilter", UpdateRowsByFilter, "批量过滤条件进行批量更新表单数据", server.Login)
	server.Post("/api/Cgs/Worksheet/DeleteRow", DeleteRow, "删除一条表单数据", server.Login)
	server.Post("/api/Cgs/Worksheet/DeleteRowBatch", DeleteRowBath, "批量删除表单数据", server.Login)
	server.Post("/api/Cgs/ImportExcel", ImportExcel, "导入excel数据", server.Login)

	server.Get("/api/Cgs/Worksheet/ApiData", getApiData, "获取api数据", server.Login)
	server.Post("/api/Cgs/Worksheet/AddFromFields", AddFromFields, "根据字段生成表单", server.None)

	server.Get("/api/Cgs/Worksheet/GetMaxMinValue", getMaxMinValue, "获取最大最小值", server.None)

	server.Post("/api/Cgs/Worksheet/export-excel", exportExcel, "表单数据导出到EXCEL", server.Login)

}

// exportExcel 导出表单数据到 excel
func exportExcel(w http.ResponseWriter, r *http.Request) {
	var filterParam FilterParam
	err := helper.ReadRequestBody(&filterParam, w, r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	err = helper.GetValidator().Struct(&filterParam)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}

	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail("NodeId is required"))
		return
	}
	service := NewWorksheetService()
	excel, name, err := service.Export2Excel(filterParam)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	head := w.Header()
	head.Set("content-type", "application/octet-stream")
	head.Set("Content-Disposition", fmt.Sprintf("attachment;filename=%s.xlsx", url.QueryEscape(name)))
	_ = excel.Write(w)
}

func Export(w http.ResponseWriter, r *http.Request) {
	visualId := r.FormValue("visualId")
	if visualId == "" {
		_, _ = helper.WriteJSON(w, server.CgsResult{
			Code: 300,
			Msg:  "VisualId is required.",
		})
		return
	}

	user, _ := server.GetCurrentUser(r)

	wsService := NewWorksheetService()
	err := wsService.Init()
	if err != nil {
		_, _ = helper.WriteJSON(w, server.CgsResult{
			Code: 300,
			Msg:  err.Error(),
		})
		return
	}
	zipData, err := wsService.Export(visualId, set.NewSet(), user)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.CgsResult{
			Code: 300,
			Msg:  err.Error(),
		})
		return
	}
	buf, err := base.ZipFile(zipData)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.CgsResult{
			Code: 300,
			Msg:  err.Error(),
		})
		return
	}
	_, _ = buf.WriteTo(w)
}

func GetWorksheetInfo(w http.ResponseWriter, r *http.Request) {
	// 查询列表
	visualId := r.FormValue("visualId")
	wsName := r.FormValue("wsName")     // 表格名称
	simplify := r.FormValue("simplify") // 表格名称
	// 分页
	//category, _ := strconv.ParseInt(r.FormValue("Category"), 10, 64)
	pageNo, _ := strconv.ParseInt(r.FormValue("pageNo"), 10, 64)
	pageSize, _ := strconv.ParseInt(r.FormValue("pageSize"), 10, 64)
	// 排序
	sortField := strings.TrimSpace(r.FormValue("sortField"))
	sortOrder := strings.TrimSpace(r.FormValue("sortOrder"))
	opts := options.FindOptions{
		Sort: bson.M{
			"updateTime": -1,
		},
	}
	if sortField != "" && sortOrder != "" {
		if sortOrder == "ascend" { // 升序
			opts.Sort = bson.M{
				sortField: 1,
			}
		} else {
			opts.Sort = bson.M{
				sortField: -1,
			}
		}
	}
	wsInfo := &WorksheetInfo{
		VisualId: visualId,
		WsName:   wsName,
	}
	duModel := base.GenerateDataUserModel(wsInfo, r)
	duModel.Simplify = simplify == "true"
	duModel.Options = &opts
	duModel.Page = &model.Page{
		Current: pageNo,
		Size:    pageSize,
	}
	if pageSize > 0 {
		duModel.ResolvePageOption()
	}
	wsService := NewWorksheetService()
	result, err := wsService.List(duModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, result)
}

func GetWorksheetInfoById(w http.ResponseWriter, r *http.Request) {
	worksheetId, err := primitive.ObjectIDFromHex(r.FormValue("id"))
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail("NodeId is required"))
		return
	}
	wsInfo := &WorksheetInfo{
		Id: worksheetId,
	}

	duModel := base.GenerateDataUserModel(wsInfo, r)
	wsService := NewWorksheetService()
	result, err := wsService.GetOne(duModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK().WithData(result))
}

func Add(w http.ResponseWriter, r *http.Request) {
	wsInfo := &WorksheetInfo{}
	err := helper.ReadRequestBody(wsInfo, w, r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}

	dataUserModel := base.GenerateDataUserModel(wsInfo, r)
	wsService := NewWorksheetService()
	err = wsService.Save(dataUserModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK("Add successfully!").WithData(bson.M{
		"worksheetId": wsInfo.Id,
	}))
}

func UpdateName(w http.ResponseWriter, r *http.Request) {
	id, err := primitive.ObjectIDFromHex(strings.TrimSpace(r.FormValue("id")))
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail("NodeId is not allowed empty."))
		return
	}
	wsName := strings.TrimSpace(r.FormValue("wsName"))
	if wsName == "" {
		_, _ = helper.WriteJSON(w, server.Fail("wsName is not allowed empty."))
		return
	}
	// 所属应用
	visualData := r.Form["visualData"]
	wsInfo := &WorksheetInfo{
		Id:         id,
		WsName:     wsName,
		VisualData: visualData,
	}
	duModel := base.GenerateDataUserModel(wsInfo, r)
	wsService := NewWorksheetService()
	err = wsService.Update(duModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK("Update successfully!"))
}

func Update(w http.ResponseWriter, r *http.Request) {
	wsInfo := &WorksheetInfo{}
	err := helper.ReadRequestBody(wsInfo, w, r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	dataUserModel := base.GenerateDataUserModel(wsInfo, r)
	wsService := NewWorksheetService()
	err = wsService.Update(dataUserModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK("Update successfully!"))
}

func UpdateFields(w http.ResponseWriter, r *http.Request) {
	wsInfo := &WorksheetInfo{}
	err := helper.ReadRequestBody(wsInfo, w, r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	dataUserModel := base.GenerateDataUserModel(wsInfo, r)
	wsService := NewWorksheetService()
	err = wsService.UpdateFields(dataUserModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK("Update successfully!"))
}

// 逻辑删除表单
func DeleteLogic(w http.ResponseWriter, r *http.Request) {
	id, err := primitive.ObjectIDFromHex(strings.TrimSpace(r.FormValue("id")))
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail("NodeId is not allowed empty!"))
	}
	wsInfo := &WorksheetInfo{
		Id: id,
	}
	dataUserModel := base.GenerateDataUserModel(wsInfo, r)
	wsService := NewWorksheetService()
	err = wsService.RemoveLogic(dataUserModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK("Delete successfully!"))
}

// 添加表单数据
func AddRow(w http.ResponseWriter, r *http.Request) {
	wsRowData := &WsRowData{}
	err := helper.ReadRequestBody(wsRowData, w, r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}

	dataUserModel := base.GenerateDataUserModel(wsRowData, r)
	wsService := NewWorksheetService()
	err = wsService.AddRow(dataUserModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK("Add successfully!").WithData(bson.M{
		"rowId": wsRowData.RowId,
	}))
}

// 批量新增
func AddRows(w http.ResponseWriter, r *http.Request) {
	// appKey, sign, worksheetId, rows []
	rowDataVo := &BatchAddRowVo{}
	err := helper.ReadRequestBody(rowDataVo, w, r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}

	validator := helper.GetValidator()
	err = validator.Struct(rowDataVo)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail("参数缺少"))
		return
	}
	if len(rowDataVo.Rows) == 0 {
		_, _ = helper.WriteJSON(w, server.Fail("数据不能为空"))
		return
	}
	dataUserModel := base.GenerateDataUserModel(rowDataVo, r)
	wsService := NewWorksheetService()
	err = wsService.BatchAddRow(dataUserModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK("Add successfully!"))
}

// 更新记录
func UpdateRow(w http.ResponseWriter, r *http.Request) {
	wsRowData := &WsRowData{}
	err := helper.ReadRequestBody(wsRowData, w, r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	if wsRowData.RowId == "" {
		_, _ = helper.WriteJSON(w, server.Fail("rowId is required"))
		return
	}

	dataUserModel := base.GenerateDataUserModel(wsRowData, r)
	wsService := NewWorksheetService()
	err = wsService.UpdateRow(dataUserModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK("Update successfully!"))
}

func UpdateRowBatch(w http.ResponseWriter, r *http.Request) {
	wsRowDataBatch := &WsRowDataBatch{}
	err := helper.ReadRequestBody(wsRowDataBatch, w, r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	if len(wsRowDataBatch.RowIds) == 0 && !wsRowDataBatch.IsAll {
		_, _ = helper.WriteJSON(w, server.Fail("rowId is required"))
		return
	}

	dataUserModel := base.GenerateDataUserModel(wsRowDataBatch, r)
	wsService := NewWorksheetService()
	err = wsService.UpdateRowBatch(dataUserModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK("Update successfully!"))
}

// 批量根据过滤条件批量修改
func UpdateRowsByFilter(w http.ResponseWriter, r *http.Request) {
	wsRowDataBatchByFilter := &WsRowDataBatchByFilter{}

	err := helper.ReadRequestBody(wsRowDataBatchByFilter, w, r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	/*if len(wsRowDataBatch.RowIds) == 0 && !wsRowDataBatch.IsAll {
		_, _ = helper.WriteJSON(w, server.Fail("rowId is required"))
		return
	}*/
	if wsRowDataBatchByFilter.WorksheetId.IsZero() || len(wsRowDataBatchByFilter.UpdateSections) == 0 {
		_, _ = helper.WriteJSON(w, server.Fail("worksheetId or updateSections is required"))
		return
	}

	dataUserModel := base.GenerateDataUserModel(nil, r)
	wsService := NewWorksheetService()

	errs := []bson.M{}
	for i := range wsRowDataBatchByFilter.UpdateSections {
		wsRowDataBatch := wsRowDataBatchByFilter.UpdateSections[i]
		wsRowDataBatch.IsAll = true
		wsRowDataBatch.WorksheetId = wsRowDataBatchByFilter.WorksheetId
		dataUserModel.Data = &wsRowDataBatch
		err = wsService.UpdateRowBatch(dataUserModel)
		if err != nil {
			errs = append(errs, bson.M{
				"error": err,
				"index": i,
			})
		}
	}
	if len(errs) > 0 {
		_, _ = helper.WriteJSON(w, server.Fail("Update error!").WithData(errs))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK("Update successfully!"))
}

// 删除记录
func DeleteRow(w http.ResponseWriter, r *http.Request) {
	worksheetId, err := primitive.ObjectIDFromHex(r.FormValue("worksheetId"))
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail("WorksheetId is not allowed empty."))
		return
	}
	/*rowId, err := primitive.ObjectIDFromHex(strings.TrimSpace(r.FormValue("rowId")))
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail("RowId is not allowed empty."))
		return
	}*/
	rowId := r.FormValue("rowId")
	if rowId == "" {
		_, _ = helper.WriteJSON(w, server.Fail("RowId is not allowed empty."))
		return
	}
	wsRowData := &WsRowData{
		WorksheetId: worksheetId,
		RowId:       rowId,
	}
	dataUserModel := base.GenerateDataUserModel(wsRowData, r)
	wsService := NewWorksheetService()
	err = wsService.DeleteRowLogic(dataUserModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK("Delete successfully!"))
}

// 批量删除
func DeleteRowBath(w http.ResponseWriter, r *http.Request) {
	batchDeleteRowVo := &BatchDeleteRowVo{}
	err := helper.ReadRequestBody(batchDeleteRowVo, w, r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}

	dataUserModel := base.GenerateDataUserModel(batchDeleteRowVo, r)
	wsService := NewWorksheetService()
	err = wsService.BatchDeleteRow(dataUserModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK("Delete successfully!"))
}

func ImportExcel(w http.ResponseWriter, r *http.Request) {
	importExcelVo := &ImportExcelVo{}
	err := helper.ReadRequestBody(importExcelVo, w, r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	if importExcelVo.WorksheetId.IsZero() {
		_, _ = helper.WriteJSON(w, server.Fail("WorksheetId is not allowed empty."))
		return
	}
	dataUserModel := base.GenerateDataUserModel(importExcelVo, r)
	wsService := NewWorksheetService()
	err = wsService.ImportExcelData(dataUserModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK("Import successfully!").WithData(bson.M{
		"fieldsData": importExcelVo.RowList,
		"errorData":  importExcelVo.Errors,
	}))
}

func getApiData(w http.ResponseWriter, r *http.Request) {
	data, err := GetApiData()
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	helper.WriteJSON(w, server.OK("Get successfully!").WithData(data))
}

func AddFromFields(w http.ResponseWriter, r *http.Request) {
	kFormDesignVo := &KFormDesignVo{}
	err := helper.ReadRequestBody(kFormDesignVo, w, r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	wsInfo, err := kFormDesignVo.ToWorksheetInfo()
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}

	dataUserModel := base.GenerateDataUserModel(wsInfo, r)
	wsService := NewWorksheetService()
	err = wsService.Save(dataUserModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK("Add successfully!").WithData(bson.M{
		"worksheetId": wsInfo.Id,
	}))
}

// 获取最大最小值
func getMaxMinValue(w http.ResponseWriter, r *http.Request) {
	var filterParam FilterParam
	err := helper.ReadRequestBody(&filterParam, w, r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}

	if filterParam.SortField == "" {
		_, _ = helper.WriteJSON(w, server.Fail("SortField is required."))
		return
	}

	dataUserModel := base.GenerateDataUserModel(&filterParam, r)
	wsService := NewWorksheetService()
	data, err := wsService.GetMaxMinValue(dataUserModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK("Get successfully!").WithData(data))
}
